using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;


namespace iDorm
{
	// Renderer
	// Handles any low level rendering and is the exclusive entry point 
	// to the direct3D library.

	public class Renderer
	{
		private Device device;
		private PresentParameters pp;
		
		Microsoft.DirectX.Direct3D.Font font;

		Matrix matView;

		// Constructor
		//
		// Description: Creates a standard device and sets parameters to 
		//				default values
		// Input:		Form - where to render the graphics
		// Output:		None
		public Renderer(System.Windows.Forms.Panel target)
		{
			pp = new PresentParameters();
			pp.SwapEffect = SwapEffect.Discard;
			pp.Windowed = true;
			pp.EnableAutoDepthStencil = true;
			pp.AutoDepthStencilFormat = DepthFormat.D24S8;
			pp.PresentationInterval = PresentInterval.One;

			try
			{
				device = new Device(0, DeviceType.Hardware, target, 
									CreateFlags.SoftwareVertexProcessing, pp); 
			}
			catch (DirectXException)
			{
				MessageBox.Show("Unable to initialize DirectX");
				Application.Exit();
			}

			// Setup lighting
			device.RenderState.Lighting = true;
			device.Lights[0].Type = LightType.Directional;
			device.Lights[0].Direction = new Vector3(0, -1, 0);
			device.Lights[0].Diffuse = Color.White;
			device.Lights[0].Enabled = true;
			device.Lights[0].Commit();

			device.RenderState.Ambient = Color.White;

			font = new Microsoft.DirectX.Direct3D.Font(device, new System.Drawing.Font("Arial", 12));
		}

		// BeginRenderD
		public void BeginRender(Color backcolor)
		{
			device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, backcolor, 1.0f, 0);
			device.BeginScene();

			// Now the device is prepared to write to the back buffer
		}
		// Ends rendering
		public void EndRender()
		{
			device.EndScene();
			device.Present();
		}
		// Switches from 2d to 3d perspective
		public void Switch3D()
		{
			device.SetTransform(TransformType.Projection,
								Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, 1.0f, 1.0f, 1000.0f));
			
			matView = Matrix.LookAtLH(new Vector3(-15, 15, -15), new Vector3(0,0,0), new Vector3(0,1,0));

			device.SetTransform(TransformType.View, matView);
		}
		// Switches from 3d to 2d perspecive
		public void Switch2D()
		{
			device.SetTransform(TransformType.Projection,
								Matrix.OrthoLH(16.0f, 16.0f, 1.0f, 100.0f));
			device.SetTransform(TransformType.View,
								Matrix.LookAtLH(new Vector3(0, 30, 0), new Vector3(0,0,0), new Vector3(0,0,1)));
		}

		public Device GetDevice()
		{
			return device;
		}
		// Prints the text of the object on the screen
		public void DrawTextCentered(string text, int x, int y, int width, int height, uint color)
		{
			int left = x - width / 2;
			int top = y - height / 2;

			font.DrawText(null, text, new System.Drawing.Rectangle(left, top, width, height), DrawTextFormat.Center | DrawTextFormat.VerticalCenter, Color.FromArgb((int)color));
		}
		// Rotate the screen for walkthrough
		public void RotateAroundCenter(float angle)
		{
			Matrix matTmp = Matrix.LookAtLH(new Vector3(21.21f * (float)Math.Sin(angle), 15, 21.21f * (float)Math.Cos(angle)), new Vector3(0,0,0), new Vector3(0,1,0));
			device.SetTransform(TransformType.View, matTmp);
		}
	}
}
